home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 May / macformat-024.iso / Shareware City / Developers / nshellmegasource1.50 / mega src / commands / launch.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-24  |  8.7 KB  |  362 lines  |  [TEXT/KAHL]

  1. /* ========== the commmand file: ==========
  2.  
  3.     launch.c
  4.         
  5.     Copyright (c) 1993,1994 Newport Software Development
  6.     
  7.     You may distribute unmodified copies of this file for
  8.     noncommercial purposes.  You may use this file as a
  9.     reference when writing your own nShell(tm) commands.
  10.     
  11.     All other rights are reserved.
  12.     
  13.    ========== the commmand file: ========== */
  14.  
  15. #ifdef __MWERKS__            // CodeWarrior requires an A4 setup
  16. #include <A4Stuff.h>
  17. #endif
  18.  
  19. #include <Aliases.h>
  20. #include <appleevents.h>
  21. #include <GestaltEqu.h>
  22. #include <processes.h>
  23.  
  24. #include "nshc.h"
  25.  
  26. #include "arg_utl.proto.h"
  27. #include "fss_utl.proto.h"
  28. #include "nshc_utl.proto.h"
  29. #include "str_utl.proto.h"
  30.  
  31. /* ======================================== */
  32.  
  33. // prototypes
  34.  
  35. int        Pre7( void );
  36. int        is_it_running( OSType targetSignature );
  37. int        launch( int gotFSSpec, FSSpec *launchApp, FSSpec *launchDoc, t_nshc_calls *nshc_calls );
  38. OSErr    odoc( int gotFSSpec, FSSpec *doc_fss, OSType app_sig, t_nshc_calls *nshc_calls );
  39.  
  40. /* ======================================== */
  41.  
  42. // return true if 'sysv' is previous to 7.0
  43.  
  44. int    Pre7( void )
  45. {
  46.     OSErr    error;
  47.     long    response;
  48.     
  49.     if ( error = Gestalt( 'sysv', &response ) )
  50.         return(true);
  51.         
  52.     if ( response < 0x700 )
  53.         return(true);
  54.     else
  55.         return(false);
  56. }
  57.  
  58. /* ======================================== */
  59.  
  60. int    is_it_running( OSType targetSignature )
  61. {
  62.     Str255                    name;
  63.     ProcessSerialNumber        psn_p;
  64.     ProcessInfoRec          pi;
  65.             
  66.     pi.processName       = name;
  67.     pi.processInfoLength = sizeof(pi);
  68.     pi.processAppSpec    = NULL;
  69.     
  70.     psn_p.highLongOfPSN = 0;
  71.     psn_p.lowLongOfPSN  = kNoProcess;
  72.         
  73.     while(!GetNextProcess(&psn_p))
  74.         if(!GetProcessInformation(&psn_p,&pi))
  75.             if ( pi.processSignature == targetSignature )
  76.                 return( 1 );
  77.  
  78.     return( 0 );
  79. }
  80.  
  81. /* ======================================== */
  82.  
  83. int launch( int gotFSSpec, FSSpec *launchApp, FSSpec *launchDoc, t_nshc_calls *nshc_calls )
  84. {    
  85.     AEDesc                docDesc;
  86.     AEDesc                parmDesc;
  87.     AEDesc                adrDesc;
  88.     AEDescList            docList;
  89.     AliasHandle            docAlias;
  90.     AppleEvent            fakeEvent;
  91.     AppParametersPtr    docParm;
  92.     LaunchParamBlockRec    launchThis;
  93.     OSErr                myErr;
  94.     ProcessSerialNumber myPSN;
  95.     
  96.     // initialize
  97.     
  98.     docDesc.dataHandle = nil;
  99.     parmDesc.dataHandle = nil;
  100.     adrDesc.dataHandle = nil;
  101.     docList.dataHandle = nil;
  102.     docAlias = nil;
  103.     fakeEvent.dataHandle = nil;
  104.  
  105.     GetCurrentProcess(&myPSN);        // used to initialize new AE things
  106.     
  107.     // create the address desc for the event
  108.     
  109.     myErr = AECreateDesc(typeProcessSerialNumber, (Ptr)&myPSN, sizeof(ProcessSerialNumber), &adrDesc);
  110.     if (myErr) goto Cleanup;
  111.  
  112.     // stuff it in my launch parameter block
  113.     
  114.     launchThis.launchAppSpec = launchApp;
  115.     
  116.     if (launchDoc) {
  117.         
  118.         // create an apple event for "open doc"
  119.         myErr = AECreateAppleEvent(kCoreEventClass, kAEOpenDocuments, &adrDesc, kAutoGenerateReturnID, kAnyTransactionID, &fakeEvent);
  120.         if (myErr) goto Cleanup;
  121.  
  122.         // create a list to hold the doc alias
  123.         myErr = AECreateList(nil, 0, false, &docList);
  124.         if (myErr) goto Cleanup;
  125.     
  126.         // ae needs an alias to the doc
  127.         myErr = NewAlias(nil, launchDoc, &docAlias);
  128.         if (myErr) goto Cleanup;
  129.  
  130.         // and a descriptor for the alias
  131.         HLock((Handle)docAlias);
  132.         myErr = AECreateDesc(typeAlias, (Ptr)*docAlias, GetHandleSize((Handle)docAlias), &docDesc);
  133.         HUnlock((Handle)docAlias);
  134.         if (myErr) goto Cleanup;
  135.     
  136.         // the descriptor goes in the list
  137.         myErr = AEPutDesc(&docList, 0, &docDesc);
  138.         if (myErr) goto Cleanup;
  139.         
  140.         // and the list goes into the event
  141.         myErr = AEPutParamDesc(&fakeEvent, keyDirectObject, &docList);
  142.         if (myErr) goto Cleanup;
  143.     
  144.         // but the fake event is REALLY a parameter!
  145.         myErr = AECoerceDesc(&fakeEvent, typeAppParameters, &parmDesc);
  146.         if (myErr) goto Cleanup;
  147.         
  148.         docParm = (AppParametersPtr)*(parmDesc.dataHandle);
  149.         }
  150.     else
  151.         docParm = nil;
  152.     
  153.     // stuff the LaunchParamBlockRec and send it
  154.     
  155.     HLock((Handle)fakeEvent.dataHandle);
  156.     
  157.     launchThis.launchAppParameters = docParm;
  158.     launchThis.launchBlockID = extendedBlock;
  159.     launchThis.launchEPBLength = extendedBlockLen;
  160.     launchThis.launchFileFlags = 0;
  161.     launchThis.launchControlFlags = launchContinue + launchNoFileFlags;
  162.     
  163.     myErr = LaunchApplication(&launchThis);
  164.     
  165.     HUnlock((Handle)fakeEvent.dataHandle);
  166.     
  167. Cleanup:
  168.  
  169.     if (myErr) nshc_calls->NSH_putStr_err("\plaunch: Message could not be sent.\r");
  170.     
  171.     if ( docDesc.dataHandle ) AEDisposeDesc(&docDesc);
  172.     if ( parmDesc.dataHandle ) AEDisposeDesc(&parmDesc);
  173.     if ( adrDesc.dataHandle ) AEDisposeDesc(&adrDesc);
  174.     if ( docList.dataHandle ) AEDisposeDesc(&docDesc);
  175.     if ( fakeEvent.dataHandle )AEDisposeDesc(&fakeEvent);
  176.  
  177.     if ( docAlias ) DisposeHandle((Handle)docAlias);
  178.  
  179.     return(myErr);
  180. }
  181.  
  182. /* ======================================== */
  183.  
  184. OSErr odoc( int gotFSSpec, FSSpec *doc_fss, OSType app_sig, t_nshc_calls *nshc_calls )
  185. {
  186.     OSErr            myErr;
  187.     FInfo            finfo;
  188.     int                appRunning;
  189.     AEDesc            appDesc;
  190.     AliasHandle        docAlias;
  191.     AppleEvent        openAE;
  192.     AppleEvent        replyAE;
  193.     AEDescList        docList;
  194.     
  195.     // initialize
  196.     
  197.     openAE.dataHandle = nil;
  198.     replyAE.dataHandle = nil;
  199.     appDesc.dataHandle = nil;
  200.     docList.dataHandle = nil;
  201.     
  202.     docAlias = nil;
  203.             
  204.     // see if the app is running
  205.     
  206.     appRunning = is_it_running( app_sig );
  207.     
  208.     if (!appRunning) {
  209.         nshc_calls->NSH_putStr_err("\podoc: Target process is not running\r");
  210.         return(1);
  211.         }
  212.  
  213.     myErr = AECreateDesc(typeApplSignature,
  214.                          (Ptr)&app_sig,
  215.                          sizeof(app_sig),
  216.                          &appDesc);
  217.     if (myErr) goto Cleanup;    
  218.                          
  219.     myErr = NewAlias(nil,doc_fss,&docAlias);
  220.     if (myErr) goto Cleanup;    
  221.  
  222.     myErr = AECreateAppleEvent(kCoreEventClass,
  223.                                kAEOpenDocuments,
  224.                                &appDesc,
  225.                                kAutoGenerateReturnID,
  226.                                kAnyTransactionID,
  227.                                &openAE);
  228.     if (myErr) goto Cleanup;    
  229.  
  230.     myErr = AECreateList(nil,0,false,&docList);
  231.     if (myErr) goto Cleanup;    
  232.  
  233.     HLock( (Handle)docAlias );
  234.     myErr = AEPutPtr(&docList,
  235.                      0,
  236.                      typeAlias,
  237.                      (Ptr)*docAlias,
  238.                      sizeof(AliasHandle)+(**docAlias).aliasSize);
  239.     HUnlock( (Handle)docAlias );
  240.     if (myErr) goto Cleanup;    
  241.  
  242.     myErr = AEPutParamDesc(&openAE,keyDirectObject,&docList);
  243.     if (myErr) goto Cleanup;
  244.     
  245.     myErr = AESend(&openAE,&replyAE,kAENoReply,kAENormalPriority,kAEDefaultTimeout,nil,nil);
  246.         
  247. Cleanup:
  248.  
  249.     if (myErr) nshc_calls->NSH_putStr_err("\podoc: Message could not be sent.\r");
  250.     
  251.     if (docList.dataHandle) AEDisposeDesc(&docList);
  252.     if (openAE.dataHandle) AEDisposeDesc(&openAE);
  253.     if (replyAE.dataHandle) AEDisposeDesc(&replyAE);
  254.     if (appDesc.dataHandle) AEDisposeDesc(&appDesc);
  255.     
  256.     if (docAlias) DisposHandle( (Handle)docAlias );
  257.     
  258.     return(myErr);
  259. }
  260.  
  261. /* ======================================== */
  262.  
  263. void main(t_nshc_parms *nshc_parms, t_nshc_calls *nshc_calls)
  264. {
  265.     FInfo    finfo;
  266.     FSSpec    app_fss;
  267.     FSSpec    doc_fss;
  268.     int        gotFSSpec;
  269.     int        result;
  270.     
  271. #ifdef __MWERKS__
  272.     long oldA4  = SetCurrentA4();
  273. #endif
  274.  
  275.     nshc_parms->action = nsh_idle;        // always one pass to this command
  276.     gotFSSpec = fss_test();                // find out if fss is there
  277.     
  278.     // *** reason not to run 1 - bad included version
  279.     
  280.     if (nshc_bad_version( nshc_parms, nshc_calls, NSHC_VERSION )) {
  281.         result = NSHC_ERR_VERSION;
  282.         goto Cleanup;
  283.         }
  284.     
  285.     // *** reason not to run 2 - bad os version
  286.     
  287.     if ( Pre7() ) {
  288.         nshc_calls->NSH_putStr_err("\plaunch: This command requires System 7.\r");
  289.         result = NSHC_ERR_GENERAL;
  290.         goto Cleanup;
  291.         }
  292.         
  293.     // *** reason not to run 3 - bad parameters
  294.     
  295.     if (( nshc_parms->argc < 2 ) || ( nshc_parms->argc > 3 )) {
  296.         nshc_calls->NSH_putStr_err("\pUsage: launch app_path [doc_path]\r");
  297.         result = NSHC_ERR_PARMS;
  298.         goto Cleanup;
  299.         }
  300.         
  301.     // *** reason not to run 4 - can't find doc
  302.     
  303.     if ( nshc_parms->argc > 2 ) {
  304.     
  305.         result = arg_to_fss( nshc_parms, nshc_calls, 2, &doc_fss );
  306.     
  307.         if (!result)
  308.             result = fss_GetFInfo( gotFSSpec, &doc_fss, &finfo );
  309.     
  310.         if (result) {
  311.             nshc_calls->NSH_putStr_err("\plaunch: Document not found.\r");
  312.             result = NSHC_ERR_PARMS;
  313.             goto Cleanup;
  314.             }
  315.             
  316.         }
  317.         
  318.     // *** reason not to run 5 - can't find app
  319.     
  320.     result = arg_to_fss( nshc_parms, nshc_calls, 1, &app_fss );
  321.     
  322.     if (!result)
  323.         result = fss_GetFInfo( gotFSSpec, &app_fss, &finfo );
  324.  
  325.     if (result || (finfo.fdType != 'APPL') ) {
  326.         nshc_calls->NSH_putStr_err("\plaunch: Application not found.\r");
  327.         result = NSHC_ERR_PARMS;
  328.         goto Cleanup;
  329.         }
  330.         
  331.     // *** finally try to launch the thing
  332.     
  333.     if ( is_it_running( finfo.fdCreator ) ) {
  334.     
  335.         // if it is running but there is no doc ... don't worry
  336.     
  337.         if ( nshc_parms->argc > 2 )
  338.             result = odoc( gotFSSpec, &doc_fss, finfo.fdCreator, nshc_calls );
  339.     
  340.         }
  341.     else {
  342.         
  343.         if ( nshc_parms->argc > 2 )
  344.             result = launch( gotFSSpec, &app_fss, &doc_fss, nshc_calls );
  345.         else
  346.             result = launch( gotFSSpec, &app_fss, nil, nshc_calls );
  347.         
  348.         }
  349.     
  350.     // *** log the result and return
  351.             
  352. Cleanup:
  353.  
  354.     nshc_parms->result = result;
  355.  
  356. #ifdef __MWERKS__
  357.     SetA4(oldA4);        // CodeWarrior needs to restore A4
  358. #else
  359.     ;                    // Think needs a ; to go with the Exit label
  360. #endif
  361. }
  362.